import EmitTask from '@socket/utils/emitTask';
import { SpawnOptionsWithoutStdio, spawn } from 'child_process';
/**
 * 执行命令
 * @param emit EmitTask 实例
 * @param command 要执行的命令
 * @param args 命令参数
 * @param opts SpawnOptionsWithoutStdio 子进程选项
 * @param timeout 命令超时时间，单位为分钟，默认10分钟
 */
export default function runCommand(
  emitTask: EmitTask,
  command: string,
  args: string[],
  opts: SpawnOptionsWithoutStdio,
  timeout = 10, // 默认10分钟超时
): Promise<void> {
  return new Promise<void>((resolve, reject) => {
    const cp = spawn(command, args, opts);

    const _timeout = timeout * 60 * 1000;
    let timer: NodeJS.Timeout | null = null;

    if (_timeout > 0) {
      timer = setTimeout(() => {
        cp.kill('SIGTERM');
        emitTask.errorEnd(`命令执行超时(${timeout}ms)`);
        reject(new Error(`命令执行超时`));
      }, _timeout);
    }

    cp.stdout.on('data', chunk => {
      emitTask.info(`stdout: ${chunk.toString()}`);
    });
    cp.stderr.on('data', chunk => {
      emitTask.info(`stderr: ${chunk.toString()}`);
    });
    cp.on('close', code => {
      if (timer) clearTimeout(timer);
      if (code === 0) {
        resolve();
      } else {
        reject(`退出码: ${code}`);
      }
    });
    cp.on('error', err => {
      if (timer) clearTimeout(timer);
      reject(err);
    });
  });
}
